#!/usr/bin/awk -f # @(#) ptest2html.awk 1.0 95/09/07 # 94/06/17 john h. dubois iii (john@armory.com) # 95/09/07 Abbreviate field NAME to just "q", VALUE to the question # in hex. # This program converts purity tests in Eric Lechner's purity test format # to an html page that will allow a user to fill out a form & submit it for # processing (done by the purity-test cgi script). # This is the output of "purity format": # The Purity Test: datafile format # # If you wish to create your own datafiles for the purity test, # follow these simple intructions. # # Each block of text (questions, subject headers, etc.) is # enclosed in a "bracket" type of punctuation. # # the styles of text blocks are: # { plain text block } # [ subject header ] # ( test question ) # and < conclusion > # # Plain text blocks are just printed out character for character. # # Subject headers are prefaced by the subject number, and then # printed as text blocks. # # Questions are preceeded by their numbers, and then prompt the # user to answer the question, keeping track of the user's # current score. # # Conclusions first calculate and print the user's score for the # test, then print out the conclusion as a text block. # # If you wish to include any of the bracket punctuation in your # text, the "\" character will "escape" the next character. # # This means that to print a question with parentheses, you # would use the following format: # (have you ever created your own purity test \(like this one\)?) # the output would be this: # 1. have you ever created your own purity test (like this one)? # and then it would have asked the user for her/his answer. # # -Eric Lechner 10-26-1989 # # -----------------sample data file------------------ # { # Welcome to the purity test! # Answer all the questions, and I'll tell you # your score when you've finished the test! # } # # [First subject: clown questions] # (Can you stand on your head?) # (Can you juggle?) # (Do you own a pair of stilts?) # # [Second subject: computer programming] # (Have you programmed a computer?) # (Do you know more than 5 programming languages?) # (Do you write purity test programs for fun?) # # # --------------end of sample data file-------------- # # bye. BEGIN { # Must process all blocks before printing anything because we have to # know how many questions there are before printing FORM while ((BlockType = FindBlock()) != "EOF") ProcBlock(BlockType,Block) if (ARGC > 1) { Name = ARGV[1] sub(".*/","",Name) # Get rid of path # Push first char to upper case Name = toupper(substr(Name,1,1)) substr(Name,2) print "" Name " Purity Test" } else print "A Purity Test" print \ "
" print Questions if (InQuestList) print "" # End the last question list print "" # End subject list if (Conclusion != "") print Conclusion print \ "" print "" print "
" } function Xprint(S) { Questions = Questions "\n" S } # Sets global Block to next block, returns block type function FindBlock( Line,EndChar,ind,C,EndPat) { if ((Line = ReadLine()) == "") return "EOF" sub("^[ \t]+","",Line) # get rid of leading whitespace ind = index("({[<",C = substr(Line,1,1)) if (!ind) FileErrExit(\ "\nBad starting character for block (" C ") in line:\n" Line,1) Line = substr(Line,2) if (Line == "") Line = "\n" EndChar = substr(")}]>",ind,1) EndPat = "[^\\\\]\\" EndChar Block = "" while (Line != "") { if (substr(Line,1,1) == EndChar) break else if (match(Line,EndPat)) { Block = Block substr(Line,1,RSTART) break } else { Block = Block Line if (Line != "\n") Block = Block "\n" } Line = ReadLine() } if (Line == "") FileErrExit("Incomplete block at end of file",1) else { gsub(/\\/,"",Block) return C } } # Print header & open subject list function DoHeader(Header) { if (Header != "") if (length(Header) > 50) # Verbose header, should be printed smaller Xprint("

" Header "

\n
") else Xprint("

" Header "

\n
") Xprint("

Check all boxes for which your answer is \"yes\"

    ") InSubjList = 1 } # If InQuestList == 1, there is an ordered question list pending. function ProcBlock(BlockType,Block) { if (BlockType == "(") { # Question if (!InSubjList) DoHeader("") if (!InQuestList) { # Open a question list Xprint("
      ") InQuestList = 1 } QuestNum++ Xprint("
    1. " Block "
    2. ") } else if (BlockType == "{") { # Plain text # Comments probably should be printed with the same line breaks # as they had. gsub("\n","
      \n",Block) # Guess that the first plain text will be an intro if (!InSubjList) DoHeader(Block) else { if (InQuestList) Xprint("
      ") # Break from the last question else { # Open a question list so that justification will be consistent Xprint("
        ") InQuestList = 1 } Xprint("" Block "") } } else if (BlockType == "<") { # Conclusion # Conclusion probably should be printed with the same line breaks # as they had. gsub("\n","
        \n",Block) Conclusion = "

        " Block "

        " } else if (BlockType == "[") { # Subject header if (!InSubjList) DoHeader("") if (InQuestList) Xprint("
      ") # Finish the last question list # Subjects probably should be printed with the same line breaks # as they had. gsub("\n","
      \n",Block) Xprint("

    3. " Block "
    4. ") DidHeader = 1 InQuestList = 0 # No longer within a question list } } function ReadLine( ret) { while ((ret = getline) > 0) if (NF > 0) return $0 if (ret < 0) { print "Error reading file " FILENAME ". Exiting." | "cat 1>&2" exit 1 } else return "" } function LineErr(S) { ErrPrint("Error on line " FNR ": " S) } function FileErr(S) { ErrPrint("Error on line " FNR " of file " FILENAME ": " S) } function FileErrExit(S,ExitVal) { FileErr(S) Err = ExitVal exit(ExitVal) } #function ErrPrint(S) { # print S | "cat 1>&2" #} function ErrPrint(S) { print S > "/dev/stderr" close("/dev/stderr") # flush output }